/**********************************************************************************
// Geometry Header File
//
// Creation:	05 Oct 2007
// Updated:		27 May 2011
// Compiler:	Visual Studio 2010
//
// Notes:		Group all the definitions of geometric forms
//				Define classes for point, line, rectangle, circle and polygon
//
**********************************************************************************/

#ifndef _ANABELE_GEOMETRY_H_
#define _ANABELE_GEOMETRY_H_

#include "GameObject.h"		// geometry is a game object
#include "Color.h"			// geometry has a color

/**********************************************************************************/
// Geometry
/**********************************************************************************/
class DLL Geometry : public GameObject
{
public:
	Color color;										// color of the geometry

	Geometry()											// constructor
	{ color = Color(255,255,255); }
};


/**********************************************************************************/
// Point
/**********************************************************************************/
class DLL Point : public Geometry
{

public:
	Point();											// default constructor
	Point(float xPos, float yPos);						// constructor using floating-point numbers
	Point(int xPos, int yPos);							// constructor using integer numbers
	
	void Rotate(float angle) {};						// rotate the point by the given angle
	void Scale(float xScale, float yScale);				// scale the point by the given factors
	void Draw();										// draw the point on screen

	float Distance(Point & p) const;					// computes the precise distance
	float FastDistance(Point & p) const;				// computes the distance with 3.5% error
	
};


/**********************************************************************************/
// Line
/**********************************************************************************/
class DLL Line : public Geometry
{
private:
	Point a, b;											// line goes from point A to point B

	int	 ClipLine(int &x1, int &y1, int &x2, int &y2);				// clip the line for the viewport
	void DrawLine(int a1, int b1, int a2, int b2, DWORD color);		// draw line using fast algorithm
	void PlotLine(int x, int y, int flag, DWORD color);				// plot pixels for DrawLine method
	
public:
	Line();												// default constructor
	Line(float x1, float y1, float x2, float y2);		// constructor using floating-point numbers
	Line(int x1, int y1, int x2, int y2);				// constructor using integer numbers
	Line(Point& pa, Point& pb);							// constructor using points

	void Rotate(float angle);							// rotate the line by the given angle
	void Scale(float xScale, float yScale);				// scale the line by the given factors
	void Draw();										// draw the line on screen

	int X1() const { return int(x + a.x); }				// x world coordinate of the beginning of the line
	int Y1() const { return int(y + a.y); }				// y world coordinate of the beginning of the line
	int X2() const { return int(x + b.x); }				// x world coordinate of the ending of the line
	int Y2() const { return int(y + b.y); }				// y world coordinate of the ending of the line

};

/**********************************************************************************/
// Rect
/**********************************************************************************/
class DLL Rect : public Geometry
{
private:
	float left;													// rectangle left coordinate
	float top;													// rectangle top coordinate
	float right;												// rectangle right coordinate
	float bottom;												// rectangle bottom coordinate

public:
	Rect();														// default constructor
	Rect(float x1, float y1, float x2, float y2);				// constructor using floating-point coordinates
	Rect(Point& a, Point& b);									// constructor using two points

	void  Rotate(float angle) {};								// rotate the rectangle by the given angle
	void  Scale(float xScale, float yScale);					// scale the rectangle by the given factors
	void  Draw();												// draw the rectangle on screen

	int   IntLeft() const   { return int(x + left); }			// return integer representation of left coordinate
	int   IntTop() const    { return int(y + top); }			// return integer representation of top coordinate
	int   IntRight() const  { return int(x + right); }			// return integer representation of right coordinate
	int   IntBottom() const { return int(y + bottom); }			// return integer representation of bottom coordinate

	float GetLeft() const   { return x + left; }				// return left coordinate
	float GetTop() const    { return y + top; }					// return top coordinate
	float GetRight() const  { return x + right; }				// return right coordinate
	float GetBottom() const { return y + bottom; }				// return bottom coordinate
};

/**********************************************************************************/
// Circle
/**********************************************************************************/
class DLL Circle : public Geometry
{
private:
	float radius;												// circle radius

public:
	Circle();													// default constructor
	Circle(float r);											// constructor with radius

	void  Rotate(float angle) {};								// rotate the circle by the given angle
	void  Scale(float xScale, float yScale);					// scale the circle by the given factors
	void  Draw();												// draw the circle on screen

	int   IntRadius() const { return int(radius); }				// return integer representation of circle's radius
	float GetRadius() const { return radius; }					// return circle's radius	
};


/**********************************************************************************/
// Poly
/**********************************************************************************/
class DLL Poly : public Geometry
{
private:
	Circle    boundingBox;										// bounding box for collision detection
	
	// private member function
	void      BoundingCircle();									// calculate and set the polygon bounding circle

public:
	int       vertexCount;										// number of vertices 
	Point*    vertexList;										// array of the polygon's vertices

	Poly();														// default constructor
	Poly(const Point * vList, int vCount);						// constructor
	Poly(const Poly& p);										// copy constructor
	~Poly();													// destructor

	// needed because there is a pointer in the member list
	const Poly& operator=(const Poly& p);						// assignement operator
	
	// overriden functions
	void Translate(float dx, float dy);							// move the object by the given delta
	void MoveTo(float px, float py);							// move the object to the given coordinates	
	void MoveTo(int px, int py);								// move the object to the given coordinates	
	void Rotate(float angle);									// rotate the polygon by the given angle
	void Scale(float xScale, float yScale);						// scale the polygon by the given factors
	void Draw();												// draw the poly on screen
	
	void SetVertices(const Point * vList, int vCount);			// set poly vertex list based on the pointed list
	Circle& GetBBox() { return boundingBox; }					// get the bounding box
}; 

/**********************************************************************************/

#endif
